package com.smart.community.region.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.smart.community.commons.annotation.ApiLog;
import com.smart.community.commons.enums.ApiLogOperationType;
import com.smart.community.commons.result.Result;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.region.dto.RegionDTO;
import com.smart.community.region.dto.RegionQueryDTO;
import com.smart.community.region.dto.RegionStatsVO;
import com.smart.community.region.dto.RegionTreeVO;
import com.smart.community.region.dto.RegionVisualizationDTO;
import com.smart.community.region.entity.Region;
import com.smart.community.region.service.IRegionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.List;

/**
 * 区域管理控制器
 * 
 * @author Wu.Liang
 * @since 2024-12-21
 */
@Slf4j
@RestController
@RequestMapping("/region")
@Tag(name = "区域管理", description = "区域管理相关接口")
public class RegionController {

	@Autowired
	private IRegionService regionService;


	// ==================== 基础CRUD接口 ====================

	/**
	 * 分页查询区域列表
	 * 
	 * @param queryDTO 查询条件
	 * @return 区域分页列表
	 * @throws Exception 统一异常
	 */
    @GetMapping
    @Operation(summary = "分页查询区域列表", description = "根据条件分页查询区域列表")
	public Result<IPage<Region>> getRegionPage(@Parameter(description = "查询条件") RegionQueryDTO queryDTO) throws Exception {
		try {
			log.info("开始分页查询区域列表，查询条件：{}", queryDTO);
			
			// 权限控制
			Long currentUserId = SecurityUtils.getCurrentUserId();
			if (currentUserId == null) {
				return Result.fail("用户未登录");
			}
			
			IPage<Region> result = regionService.getRegionPage(queryDTO);
			
			log.info("分页查询区域列表成功，返回记录数：{}", result.getRecords().size());
			return Result.success("查询成功", result);
		} catch (Exception e) {
			log.error("分页查询区域列表失败，查询条件：{}，错误信息：{}", queryDTO, e.getMessage(), e);
			return Result.fail("查询失败：" + e.getMessage());
		}
	}

	/**
	 * 获取区域详情
	 * 
	 * @param regionId 区域ID
	 * @return 区域详情
	 * @throws Exception 统一异常
	 */
	@GetMapping("/{regionId}")
	@Operation(summary = "获取区域详情", description = "根据区域ID获取区域详细信息")
	public Result<Region> getRegionById(@Parameter(description = "区域ID") @PathVariable Long regionId) throws Exception {
		try {
			log.info("开始获取区域详情，区域ID：{}", regionId);
			
			// 参数校验
			if (regionId == null || regionId <= 0) {
				return Result.fail("区域ID必须大于0");
			}
			
			// 权限控制
			Long currentUserId = SecurityUtils.getCurrentUserId();
			if (currentUserId == null) {
				return Result.fail("用户未登录");
			}
			
			Region region = regionService.getById(regionId);
			if (region == null) {
				return Result.fail("区域不存在");
			}
			
			log.info("获取区域详情成功，区域ID：{}", regionId);
			return Result.success("查询成功", region);
		} catch (Exception e) {
			log.error("获取区域详情失败，区域ID：{}，错误信息：{}", regionId, e.getMessage(), e);
			return Result.fail("查询失败：" + e.getMessage());
		}
	}

	/**
	 * 创建区域
	 * 
	 * @param regionDTO 区域信息
	 * @return 创建结果
	 * @throws Exception 统一异常
	 */
	@ApiLog(logTitle = "创建区域", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.ADD)
	@PostMapping
	@Operation(summary = "创建区域", description = "创建新的区域")
	public Result<String> createRegion(@Parameter(description = "区域信息") @RequestBody @Valid RegionDTO regionDTO) throws Exception {
		try {
			log.info("开始创建区域，操作人：{}，区域信息：{}", SecurityUtils.getCurrentUserId(), regionDTO);
			
			// 权限控制
			Long currentUserId = SecurityUtils.getCurrentUserId();
			if (currentUserId == null) {
				return Result.fail("用户未登录");
			}
			
			// 权限控制：只有管理员可以创建区域
			if (!SecurityUtils.hasRole("admin")) {
				return Result.fail("无权限创建区域");
			}
			
			boolean result = regionService.createRegion(regionDTO);
			
			if (result) {
				log.info("创建区域成功，操作人：{}", currentUserId);
				return Result.success("创建区域成功");
			} else {
				log.error("创建区域失败，操作人：{}", currentUserId);
				return Result.fail("创建区域失败");
			}
		} catch (Exception e) {
			log.error("创建区域失败，操作人：{}，错误信息：{}", SecurityUtils.getCurrentUserId(), e.getMessage(), e);
			return Result.fail("创建区域失败：" + e.getMessage());
		}
	}

	/**
	 * 更新区域
	 * 
	 * @param regionId 区域ID
	 * @param regionDTO 区域信息
	 * @return 更新结果
	 * @throws Exception 统一异常
	 */
	@ApiLog(logTitle = "更新区域", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.UPDATE)
	@PutMapping("/{regionId}")
	@Operation(summary = "更新区域", description = "更新区域信息")
	public Result<String> updateRegion(@Parameter(description = "区域ID") @PathVariable Long regionId,
			@Parameter(description = "区域信息") @RequestBody @Valid RegionDTO regionDTO) throws Exception {
		try {
			log.info("开始更新区域，操作人：{}，区域ID：{}，区域信息：{}", SecurityUtils.getCurrentUserId(), regionId, regionDTO);
			
			// 参数校验
			if (regionId == null || regionId <= 0) {
				return Result.fail("区域ID必须大于0");
			}
			
			// 权限控制
			Long currentUserId = SecurityUtils.getCurrentUserId();
			if (currentUserId == null) {
				return Result.fail("用户未登录");
			}
			
			// 权限控制：只有管理员可以更新区域
			if (!SecurityUtils.hasRole("admin")) {
				return Result.fail("无权限更新区域");
			}
			
			regionDTO.setId(regionId);
			boolean result = regionService.updateRegion(regionDTO);
			
			if (result) {
				log.info("更新区域成功，区域ID：{}，操作人：{}", regionId, currentUserId);
				return Result.success("更新区域成功");
			} else {
				log.error("更新区域失败，区域ID：{}，操作人：{}", regionId, currentUserId);
				return Result.fail("更新区域失败");
			}
		} catch (Exception e) {
			log.error("更新区域失败，操作人：{}，区域ID：{}，错误信息：{}", SecurityUtils.getCurrentUserId(), regionId, e.getMessage(), e);
			return Result.fail("更新区域失败：" + e.getMessage());
		}
	}

	/**
	 * 删除区域
	 * 
	 * @param regionId 区域ID
	 * @return 删除结果
	 * @throws Exception 统一异常
	 */
	@ApiLog(logTitle = "删除区域", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
	@DeleteMapping("/{regionId}")
	@Operation(summary = "删除区域", description = "删除指定区域")
	public Result<String> deleteRegion(@Parameter(description = "区域ID") @PathVariable Long regionId) throws Exception {
		try {
			log.info("开始删除区域，操作人：{}，区域ID：{}", SecurityUtils.getCurrentUserId(), regionId);
			
			// 参数校验
			if (regionId == null || regionId <= 0) {
				return Result.fail("区域ID必须大于0");
			}
			
			// 权限控制
			Long currentUserId = SecurityUtils.getCurrentUserId();
			if (currentUserId == null) {
				return Result.fail("用户未登录");
			}
			
			// 权限控制：只有管理员可以删除区域
			if (!SecurityUtils.hasRole("admin")) {
				return Result.fail("无权限删除区域");
			}
			
			boolean result = regionService.deleteRegion(regionId);
			
			if (result) {
				log.info("删除区域成功，区域ID：{}，操作人：{}", regionId, currentUserId);
				return Result.success("删除区域成功");
			} else {
				log.error("删除区域失败，区域ID：{}，操作人：{}", regionId, currentUserId);
				return Result.fail("删除区域失败");
			}
		} catch (Exception e) {
			log.error("删除区域失败，操作人：{}，区域ID：{}，错误信息：{}", SecurityUtils.getCurrentUserId(), regionId, e.getMessage(), e);
			return Result.fail("删除区域失败：" + e.getMessage());
		}
	}

	// ==================== 查询接口 ====================

	/**
	 * 根据区域编码获取区域
	 * 
	 * @param regionCode 区域编码
	 * @return 区域信息
	 * @throws Exception 统一异常
	 */
	@GetMapping("/code/{regionCode}")
	@Operation(summary = "根据区域编码获取区域", description = "根据区域编码获取区域信息")
	public Result<Region> getRegionByCode(@Parameter(description = "区域编码") @PathVariable String regionCode) throws Exception {
		try {
			log.info("开始根据区域编码获取区域，区域编码：{}", regionCode);
			
			// 参数校验
			if (regionCode == null || regionCode.trim().isEmpty()) {
				return Result.fail("区域编码不能为空");
			}
			
			// 权限控制
			Long currentUserId = SecurityUtils.getCurrentUserId();
			if (currentUserId == null) {
				return Result.fail("用户未登录");
			}
			
			Region region = regionService.getRegionByCode(regionCode);
			if (region == null) {
				return Result.fail("区域不存在");
			}
			
			log.info("根据区域编码获取区域成功，区域编码：{}", regionCode);
			return Result.success("查询成功", region);
		} catch (Exception e) {
			log.error("根据区域编码获取区域失败，区域编码：{}，错误信息：{}", regionCode, e.getMessage(), e);
			return Result.fail("查询失败：" + e.getMessage());
		}
	}

	/**
	 * 根据区域类型获取区域列表
	 * 
	 * @param regionType 区域类型
	 * @return 区域列表
	 * @throws Exception 统一异常
	 */
	@GetMapping("/type/{regionType}")
	@Operation(summary = "根据区域类型获取区域列表", description = "根据区域类型获取区域列表")
	public Result<List<Region>> getRegionsByType(
			@Parameter(description = "区域类型：1-省，2-市，3-区县，4-街道，5-社区") @PathVariable Integer regionType) throws Exception {
		try {
			log.info("开始根据区域类型获取区域列表，区域类型：{}", regionType);
			
			// 参数校验
			if (regionType == null || regionType <= 0) {
				return Result.fail("区域类型必须大于0");
			}
			
			// 权限控制
			Long currentUserId = SecurityUtils.getCurrentUserId();
			if (currentUserId == null) {
				return Result.fail("用户未登录");
			}
			
			List<Region> result = regionService.getRegionsByType(regionType);
			
			log.info("根据区域类型获取区域列表成功，区域类型：{}，记录数：{}", regionType, result.size());
			return Result.success("查询成功", result);
		} catch (Exception e) {
			log.error("根据区域类型获取区域列表失败，区域类型：{}，错误信息：{}", regionType, e.getMessage(), e);
			return Result.fail("查询失败：" + e.getMessage());
		}
	}

	/**
	 * 获取子区域列表
	 * 
	 * @param regionId 区域ID
	 * @return 子区域列表
	 * @throws Exception 统一异常
	 */
	@GetMapping("/{regionId}/children")
	@Operation(summary = "获取子区域列表", description = "获取指定区域的子区域列表")
	public Result<List<Region>> getChildRegions(@Parameter(description = "区域ID") @PathVariable Long regionId) throws Exception {
		try {
			log.info("开始获取子区域列表，区域ID：{}", regionId);
			
			// 参数校验
			if (regionId == null || regionId <= 0) {
				return Result.fail("区域ID必须大于0");
			}
			
			// 权限控制
			Long currentUserId = SecurityUtils.getCurrentUserId();
			if (currentUserId == null) {
				return Result.fail("用户未登录");
			}
			
			List<Region> result = regionService.getChildRegions(regionId);
			
			log.info("获取子区域列表成功，区域ID：{}，子区域数量：{}", regionId, result.size());
			return Result.success("查询成功", result);
		} catch (Exception e) {
			log.error("获取子区域列表失败，区域ID：{}，错误信息：{}", regionId, e.getMessage(), e);
			return Result.fail("查询失败：" + e.getMessage());
		}
	}

	/**
	 * 获取区域层级路径
	 * 
	 * @param regionId 区域ID
	 * @return 区域层级路径
	 * @throws Exception 统一异常
	 */
	@GetMapping("/{regionId}/path")
	@Operation(summary = "获取区域层级路径", description = "获取从根区域到指定区域的层级路径")
	public Result<List<Region>> getRegionPath(@Parameter(description = "区域ID") @PathVariable Long regionId) throws Exception {
		try {
			log.info("开始获取区域层级路径，区域ID：{}", regionId);
			
			// 参数校验
			if (regionId == null || regionId <= 0) {
				return Result.fail("区域ID必须大于0");
			}
			
			// 权限控制
			Long currentUserId = SecurityUtils.getCurrentUserId();
			if (currentUserId == null) {
				return Result.fail("用户未登录");
			}
			
			List<Region> result = regionService.getRegionPath(regionId);
			
			log.info("获取区域层级路径成功，区域ID：{}，路径长度：{}", regionId, result.size());
			return Result.success("查询成功", result);
		} catch (Exception e) {
			log.error("获取区域层级路径失败，区域ID：{}，错误信息：{}", regionId, e.getMessage(), e);
			return Result.fail("查询失败：" + e.getMessage());
		}
	}

	/**
	 * 获取区域树形结构（按需加载）
	 * 
	 * @param parentId 父区域ID
	 * @return 区域树形结构
	 * @throws Exception 统一异常
	 */
	@GetMapping("/tree")
	@Operation(summary = "获取区域树形结构", description = "获取区域树形结构，支持按需加载，不传parentId获取顶级区域，传parentId获取直接子区域")
	public Result<List<RegionTreeVO>> getRegionTree(
			@Parameter(description = "父区域ID，不传则获取顶级区域") @RequestParam(required = false) Long parentId) throws Exception {
		try {
			log.info("开始获取区域树形结构，父区域ID：{}", parentId);
			
			// 权限控制
			Long currentUserId = SecurityUtils.getCurrentUserId();
			if (currentUserId == null) {
				return Result.fail("用户未登录");
			}
			
			List<RegionTreeVO> result = regionService.getRegionTree(parentId);
			
			log.info("获取区域树形结构成功，父区域ID：{}，节点数量：{}", parentId, result.size());
			return Result.success("查询成功", result);
		} catch (Exception e) {
			log.error("获取区域树形结构失败，父区域ID：{}，错误信息：{}", parentId, e.getMessage(), e);
			return Result.fail("查询失败：" + e.getMessage());
		}
	}

	/**
	 * 获取区域完整树形结构（递归查询所有子区域）
	 * @throws Exception 
	 */
	@GetMapping("/tree/complete")
	@Operation(summary = "获取区域完整树形结构", description = "获取区域完整树形结构，递归查询所有子区域，仅用于特殊场景")
	public Result<List<RegionTreeVO>> getCompleteRegionTree(
			@Parameter(description = "父区域ID，不传则获取所有顶级区域") @RequestParam(required = false) Long parentId) throws Exception {
		List<RegionTreeVO> result = regionService.getCompleteRegionTree(parentId);
		return Result.success(result);
	}

	// ==================== 状态管理接口 ====================

	@ApiLog(logTitle = "更新区域状态", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.UPDATE)
	@PutMapping("/{regionId}/status")
	@Operation(summary = "更新区域状态", description = "更新区域启用/禁用状态")
	public Result<Boolean> updateRegionStatus(@Parameter(description = "区域ID") @PathVariable Long regionId,
			@Parameter(description = "状态：0-禁用，1-启用") @RequestParam Integer status) throws Exception {
		try {
			log.info("开始更新区域状态，操作人：{}，区域ID：{}，状态：{}", SecurityUtils.getCurrentUserId(), regionId, status);
			
			// 权限控制
			Long currentUserId = SecurityUtils.getCurrentUserId();
			if (currentUserId == null) {
				return Result.fail("用户未登录");
			}
			
			// 权限控制：只有管理员可以更新区域状态
			if (!SecurityUtils.hasRole("admin")) {
				return Result.fail("无权限更新区域状态");
			}
			
			// 参数校验
			if (regionId == null || regionId <= 0) {
				return Result.fail("区域ID不能为空或无效");
			}
			if (status == null || (status != 0 && status != 1)) {
				return Result.fail("状态值无效，只能为0（禁用）或1（启用）");
			}
			
			boolean result = regionService.updateRegionStatus(regionId, status);
			
			if (result) {
				log.info("更新区域状态成功，区域ID：{}，状态：{}，操作人：{}", regionId, status, currentUserId);
				return Result.success(true);
			} else {
				log.error("更新区域状态失败，区域ID：{}，状态：{}，操作人：{}", regionId, status, currentUserId);
				return Result.fail("更新区域状态失败");
			}
		} catch (Exception e) {
			log.error("更新区域状态失败，操作人：{}，区域ID：{}，状态：{}，错误信息：{}", SecurityUtils.getCurrentUserId(), regionId, status, e.getMessage(), e);
			return Result.fail("更新区域状态失败：" + e.getMessage());
		}
	}

	@ApiLog(logTitle = "批量更新区域状态", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.UPDATE)
	@PutMapping("/batch/status")
	@Operation(summary = "批量更新区域状态", description = "批量更新多个区域的状态")
	public Result<Boolean> batchUpdateRegionStatus(@Parameter(description = "区域ID列表") @RequestBody List<Long> regionIds,
			@Parameter(description = "状态：0-禁用，1-启用") @RequestParam Integer status) throws Exception {
		try {
			log.info("开始批量更新区域状态，操作人：{}，区域ID列表：{}，状态：{}", SecurityUtils.getCurrentUserId(), regionIds, status);
			
			// 权限控制
			Long currentUserId = SecurityUtils.getCurrentUserId();
			if (currentUserId == null) {
				return Result.fail("用户未登录");
			}
			
			// 权限控制：只有管理员可以批量更新区域状态
			if (!SecurityUtils.hasRole("admin")) {
				return Result.fail("无权限批量更新区域状态");
			}
			
			// 参数校验
			if (regionIds == null || regionIds.isEmpty()) {
				return Result.fail("区域ID列表不能为空");
			}
			if (status == null || (status != 0 && status != 1)) {
				return Result.fail("状态值无效，只能为0（禁用）或1（启用）");
			}
			
			boolean result = regionService.batchUpdateRegionStatus(regionIds, status);
			
			if (result) {
				log.info("批量更新区域状态成功，区域ID列表：{}，状态：{}，操作人：{}", regionIds, status, currentUserId);
				return Result.success(true);
			} else {
				log.error("批量更新区域状态失败，区域ID列表：{}，状态：{}，操作人：{}", regionIds, status, currentUserId);
				return Result.fail("批量更新区域状态失败");
			}
		} catch (Exception e) {
			log.error("批量更新区域状态失败，操作人：{}，区域ID列表：{}，状态：{}，错误信息：{}", SecurityUtils.getCurrentUserId(), regionIds, status, e.getMessage(), e);
			return Result.fail("批量更新区域状态失败：" + e.getMessage());
		}
	}

	@ApiLog(logTitle = "批量删除区域", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
	@DeleteMapping("/batch")
	@Operation(summary = "批量删除区域", description = "批量删除多个区域")
	public Result<Boolean> batchDeleteRegions(@Parameter(description = "区域ID列表") @RequestBody List<Long> regionIds) throws Exception {
		try {
			log.info("开始批量删除区域，操作人：{}，区域ID列表：{}", SecurityUtils.getCurrentUserId(), regionIds);
			
			// 权限控制
			Long currentUserId = SecurityUtils.getCurrentUserId();
			if (currentUserId == null) {
				return Result.fail("用户未登录");
			}
			
			// 权限控制：只有管理员可以批量删除区域
			if (!SecurityUtils.hasRole("admin")) {
				return Result.fail("无权限批量删除区域");
			}
			
			// 参数校验
			if (regionIds == null || regionIds.isEmpty()) {
				return Result.fail("区域ID列表不能为空");
			}
			
			boolean result = regionService.batchDeleteRegions(regionIds);
			
			if (result) {
				log.info("批量删除区域成功，区域ID列表：{}，操作人：{}", regionIds, currentUserId);
				return Result.success(true);
			} else {
				log.error("批量删除区域失败，区域ID列表：{}，操作人：{}", regionIds, currentUserId);
				return Result.fail("批量删除区域失败");
			}
		} catch (Exception e) {
			log.error("批量删除区域失败，操作人：{}，区域ID列表：{}，错误信息：{}", SecurityUtils.getCurrentUserId(), regionIds, e.getMessage(), e);
			return Result.fail("批量删除区域失败：" + e.getMessage());
		}
	}

	// ==================== 验证接口 ====================

	/**
	 * 检查区域编码唯一性
	 * @throws Exception 
	 */
	@GetMapping("/check/code")
	@Operation(summary = "检查区域编码唯一性", description = "检查区域编码是否已存在")
	public Result<Boolean> checkRegionCodeUnique(@Parameter(description = "区域编码") @RequestParam String regionCode,
			@Parameter(description = "排除的区域ID") @RequestParam(required = false) Long excludeRegionId) throws Exception {
		log.info("检查区域编码唯一性，区域编码：{}，排除区域ID：{}", regionCode, excludeRegionId);
		boolean isUnique = regionService.checkRegionCodeUnique(regionCode, excludeRegionId);
		return Result.success(isUnique);
	}

	// ==================== 统计接口 ====================

	/**
	 * 获取区域统计信息
	 * @throws Exception 
	 */
	@GetMapping("/statistics")
	@Operation(summary = "获取区域统计信息", description = "获取所有区域的统计信息")
	public Result<RegionStatsVO> getRegionStatistics() throws Exception {
		RegionStatsVO result = regionService.getRegionStatistics();
		return Result.success(result);
	}

	/**
	 * 获取指定区域统计信息
	 * @throws Exception 
	 */
	@GetMapping("/{regionId}/stats")
	@Operation(summary = "获取区域统计信息", description = "获取指定区域的统计信息")
	public Result<RegionStatsVO> getRegionStats(@Parameter(description = "区域ID") @PathVariable Long regionId) throws Exception {
		RegionStatsVO result = regionService.getRegionStats(regionId);
		return Result.success(result);
	}

	/**
	 * 获取区域统计列表
	 * @throws Exception 
	 */
	@GetMapping("/{regionId}/stats/list")
	@Operation(summary = "获取区域统计列表", description = "获取指定区域的历史统计数据")
	public Result<List<RegionStatsVO>> getRegionStatsList(@Parameter(description = "区域ID") @PathVariable Long regionId,
			@Parameter(description = "开始日期，格式：yyyy-MM-dd") @RequestParam(required = false) String startDate,
			@Parameter(description = "结束日期，格式：yyyy-MM-dd") @RequestParam(required = false) String endDate) throws Exception {
		List<RegionStatsVO> result = regionService.getRegionStatsList(regionId, startDate, endDate);
		return Result.success(result);
	}

	// ==================== 数据可视化接口 ====================

	/**
	 * 获取地图标记数据
	 * @throws Exception 
	 */
	@GetMapping("/visualization/map-markers")
	@Operation(summary = "获取地图标记数据", description = "获取区域、社区、楼栋的地图标记数据")
	public Result<List<RegionVisualizationDTO.MapMarker>> getMapMarkers(
			@Parameter(description = "标记类型：region-区域，community-社区，building-楼栋") @RequestParam(required = false) String type,
			@Parameter(description = "父区域ID") @RequestParam(required = false) Long parentId) throws Exception {
		List<RegionVisualizationDTO.MapMarker> result = regionService.getMapMarkers(type, parentId);
		return Result.success(result);
	}

	/**
	 * 获取区域面积热力图数据
	 * @throws Exception 
	 */
	@GetMapping("/visualization/area-heatmap")
	@Operation(summary = "获取区域面积热力图数据", description = "获取各区域面积分布数据，用于地图热力图展示")
	public Result<List<RegionVisualizationDTO.AreaHeatmap>> getAreaHeatmap(
			@Parameter(description = "父区域ID") @RequestParam(required = false) Long parentId) throws Exception {
		List<RegionVisualizationDTO.AreaHeatmap> result = regionService.getAreaHeatmap(parentId);
		return Result.success(result);
	}

	/**
	 * 获取区域人口统计（柱状图）
	 * @throws Exception 
	 */
	@GetMapping("/visualization/population-stats")
	@Operation(summary = "获取区域人口统计", description = "获取各区域人口统计数据，用于柱状图展示")
	public Result<List<RegionVisualizationDTO.PopulationStats>> getPopulationStats(
			@Parameter(description = "父区域ID") @RequestParam(required = false) Long parentId) throws Exception {
		List<RegionVisualizationDTO.PopulationStats> result = regionService.getPopulationStats(parentId);
		return Result.success(result);
	}

	/**
	 * 获取社区分布统计（饼图）
	 * @throws Exception 
	 */
	@GetMapping("/visualization/community-distribution")
	@Operation(summary = "获取社区分布统计", description = "获取社区分布数据，用于饼图展示")
	public Result<List<RegionVisualizationDTO.CommunityDistribution>> getCommunityDistribution(
			@Parameter(description = "父区域ID") @RequestParam(required = false) Long parentId) throws Exception {
		List<RegionVisualizationDTO.CommunityDistribution> result = regionService.getCommunityDistribution(parentId);
		return Result.success(result);
	}

	// ==================== 地理信息接口 ====================

	/**
	 * 地理信息查询
	 * @throws Exception 
	 */
	@GetMapping("/geo-query")
	@Operation(summary = "地理信息查询", description = "根据经纬度范围查询区域信息")
	public Result<List<Region>> geoQuery(@Parameter(description = "最小纬度") @RequestParam BigDecimal minLat,
			@Parameter(description = "最大纬度") @RequestParam BigDecimal maxLat,
			@Parameter(description = "最小经度") @RequestParam BigDecimal minLng,
			@Parameter(description = "最大经度") @RequestParam BigDecimal maxLng) throws Exception {
		List<Region> result = regionService.geoQuery(minLat, maxLat, minLng, maxLng);
		return Result.success(result);
	}

	// ==================== 缓存管理接口 ====================

	@ApiLog(logTitle = "清除区域缓存", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
	@DeleteMapping("/cache/{regionId}")
	@Operation(summary = "清除区域缓存", description = "清除指定区域的缓存")
	public Result<Boolean> clearRegionCache(@Parameter(description = "区域ID") @PathVariable Long regionId) throws Exception {
		try {
			log.info("开始清除区域缓存，操作人：{}，区域ID：{}", SecurityUtils.getCurrentUserId(), regionId);
			
			// 权限控制
			Long currentUserId = SecurityUtils.getCurrentUserId();
			if (currentUserId == null) {
				return Result.fail("用户未登录");
			}
			
			// 权限控制：只有管理员可以清除缓存
			if (!SecurityUtils.hasRole("admin")) {
				return Result.fail("无权限清除区域缓存");
			}
			
			// 参数校验
			if (regionId == null || regionId <= 0) {
				return Result.fail("区域ID不能为空或无效");
			}
			
			regionService.clearRegionCache(regionId);
			
			log.info("清除区域缓存成功，区域ID：{}，操作人：{}", regionId, currentUserId);
			return Result.success(true);
		} catch (Exception e) {
			log.error("清除区域缓存失败，操作人：{}，区域ID：{}，错误信息：{}", SecurityUtils.getCurrentUserId(), regionId, e.getMessage(), e);
			return Result.fail("清除区域缓存失败：" + e.getMessage());
		}
	}

	@ApiLog(logTitle = "清除所有区域缓存", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
	@DeleteMapping("/cache/all")
	@Operation(summary = "清除所有区域缓存", description = "清除所有区域相关的缓存")
	public Result<Boolean> clearAllRegionCache() throws Exception {
		try {
			log.info("开始清除所有区域缓存，操作人：{}", SecurityUtils.getCurrentUserId());
			
			// 权限控制
			Long currentUserId = SecurityUtils.getCurrentUserId();
			if (currentUserId == null) {
				return Result.fail("用户未登录");
			}
			
			// 权限控制：只有管理员可以清除所有缓存
			if (!SecurityUtils.hasRole("admin")) {
				return Result.fail("无权限清除所有区域缓存");
			}
			
			regionService.clearAllRegionCache();
			
			log.info("清除所有区域缓存成功，操作人：{}", currentUserId);
			return Result.success(true);
		} catch (Exception e) {
			log.error("清除所有区域缓存失败，操作人：{}，错误信息：{}", SecurityUtils.getCurrentUserId(), e.getMessage(), e);
			return Result.fail("清除所有区域缓存失败：" + e.getMessage());
		}
	}

	/**
	 * 刷新区域统计数据
	 * @throws Exception 
	 */
	@PostMapping("/{regionId}/refresh-stats")
	@Operation(summary = "刷新区域统计数据", description = "手动刷新指定区域的统计数据")
	public Result<Boolean> refreshRegionStats(@Parameter(description = "区域ID") @PathVariable Long regionId) throws Exception {
		try {
			log.info("开始刷新区域统计数据，操作人：{}，区域ID：{}", SecurityUtils.getCurrentUserId(), regionId);
			
			// 权限控制
			Long currentUserId = SecurityUtils.getCurrentUserId();
			if (currentUserId == null) {
				return Result.fail("用户未登录");
			}
			
			// 权限控制：只有管理员可以刷新统计数据
			if (!SecurityUtils.hasRole("admin")) {
				return Result.fail("无权限刷新区域统计数据");
			}
			
			// 参数校验
			if (regionId == null || regionId <= 0) {
				return Result.fail("区域ID不能为空或无效");
			}
			
			boolean result = regionService.refreshRegionStats(regionId);
			
			if (result) {
				log.info("刷新区域统计数据成功，区域ID：{}，操作人：{}", regionId, currentUserId);
				return Result.success(true);
			} else {
				log.error("刷新区域统计数据失败，区域ID：{}，操作人：{}", regionId, currentUserId);
				return Result.fail("刷新区域统计数据失败");
			}
		} catch (Exception e) {
			log.error("刷新区域统计数据失败，操作人：{}，区域ID：{}，错误信息：{}", SecurityUtils.getCurrentUserId(), regionId, e.getMessage(), e);
			return Result.fail("刷新区域统计数据失败：" + e.getMessage());
		}
	}
}